/*
 * Implemnetacion de la interfaz remota del cliente, asi como de la creación
 * del servidor
 */

package cliente.comunicacion;

import cliente.negocio.Administrador_Cliente;
import herramientas.Agente_Properties;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author tpaxle
 */

public class Cliente extends UnicastRemoteObject implements ICliente{

    private String direccion_ip= "localhost";
    private int puerto= 12999;
    private Administrador_Cliente Admin_Cliente;

    public Cliente() throws RemoteException{
        int MaxClientes_maquina= 5;
        int nreintentos=0;
        boolean conectado= false;

        /*Se leen los puertos en los que se crea el servidor cliente*/
        try{
            Agente_Properties gprop= Agente_Properties.getAgenteProperties();
            puerto= Integer.parseInt(gprop.getProperty("cliente.puerto"));
        }
        catch (FileNotFoundException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        }
        /*En caso de existir en la misma máquina otros clientes corriendo,
         * Se busca un puerto superior Se admiten 5 puertos
         */
        Admin_Cliente = new Administrador_Cliente(this);
        while(nreintentos< MaxClientes_maquina & !conectado){
            try {
                LocateRegistry.createRegistry(puerto);
                try {
                    Naming.bind("rmi://" + direccion_ip + ":" + puerto + "/Cliente", this);
                    conectado= true;
                } catch (AlreadyBoundException ex) {
                    Naming.rebind("rmi://" + direccion_ip + ":" + puerto + "/Cliente", this);
                    conectado= true;
                }
            } catch (RemoteException ex) {
                nreintentos++;
                puerto++;
            } catch (MalformedURLException ex){
                nreintentos++;
                puerto++;
            }
        }
        if(nreintentos ==5){
            JOptionPane.showConfirmDialog(null, "Demasiados clientes ejecutados en la misma máquina", "La aplicacion no puede continuar", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
         
    }


    /*  */
    public void actualizar(Object dato, int n_op) throws RemoteException {
        this.Admin_Cliente.log("El servidor se ha puesto en contacto conmigo");
    }

    /*  Desactivar el servidor cliente iniciado en la direccion direccion_ip*/
    public void desactivarservicio() throws RemoteException, NotBoundException, MalformedURLException{
        Naming.unbind("rmi://"+ direccion_ip+":"+puerto+"/Cliente");
        
    }

    /*  Funcion a través de la cual el servidor ordena al cliente desconectarse   */
    public void expulsar() throws RemoteException {
       Admin_Cliente.expularsesion();
    }

    /*  El servidor utiliza esta funcion para enviar la lista de usuairos disponible en la base de datos y el beneficiario  */
    public void recibirUsuarios(ArrayList<Object> usuarios, ArrayList<Object> beneficiarios) throws RemoteException {
         Admin_Cliente.log("Recibe usuarios");
        Admin_Cliente.entregarUsuariosrecibidos(usuarios, beneficiarios);
    }

    public void recibirCentros(ArrayList<Object> centros) throws RemoteException {
        Admin_Cliente.log("Recibe Centros");
        Admin_Cliente.entregarCentros(centros);
    }

    public void recibirMedicos(ArrayList<Object> medicos) throws RemoteException {
        Admin_Cliente.log("Recibe Medicos");
        Admin_Cliente.entregarMedicos(medicos);
    }

    public void entregarhorario(ArrayList<Object> lhora) throws RemoteException {
        Admin_Cliente.log("Recibe Horas");
        Admin_Cliente.entregarHorario(lhora);
    }

    public void notificar(int noperacion, Object d) throws RemoteException{
        Admin_Cliente.log("Se recibe una notificacion de cambio "+ noperacion);
        Admin_Cliente.notificar(noperacion, d);
     }

}
